hyprland end4自动切换neovim主题

本文最后更新于 2025年9月4日 晚上

最近我的hyprland主题一直在使用end-4做的dotfile:illogical-impulse(下面简称ii),基于Quickshell实现,虽然后台占用是大,但是我用起来非常流畅,内存不拿来用不就是浪费吗~
遇到的一个问题是, 当切换主题的日夜间模式时, neonvim的主题并不会切换,如果就用neonvim主题配置中的transparent_background = false,即背景透明,会导致在ii生成的颜色配置在直接反转颜色后很不好看,于是想着通过配置neovim的主题文件来实现自动切换。

实现的效果

🎨 自动切换

  • 启动时检测:Neovim 启动时自动检测当前桌面环境的深浅色模式
  • 匹配主题
    • 浅色模式 → 自动应用 Catppuccin Latte(浅色主题)
    • 深色模式 → 自动应用 Catppuccin Mocha(深色主题)
  • 视觉统一:编辑器主题与 Quickshell 生成的 Material Design 3 终端颜色相协调

🎯 手动切换

  • 快捷键切换
    • <leader>tl - 强制切换到浅色主题
    • <leader>td - 强制切换到深色主题
  • 命令行控制
    • :ThemeLight - 切换到浅色主题
    • :ThemeDark - 切换到深色主题

原理

🔍 检测

  1. 数据源:读取 Quickshell 生成的颜色配置文件

    • 位置:~/.local/state/quickshell/user/generated/colors.json
  2. 亮度计算

    1
    2
    3
    4
    5
    6
    7
    -- 提取背景色(如 #f6fafe 或 #101417)
    local r = tonumber(hex:sub(1, 2), 16) or 0
    local g = tonumber(hex:sub(3, 4), 16) or 0
    local b = tonumber(hex:sub(5, 6), 16) or 0

    -- 使用 ITU-R BT.709 标准计算相对亮度
    local brightness = (r * 299 + g * 587 + b * 114) / 1000
  3. 判断逻辑

    • brightness > 128 → 浅色环境 → vim.o.background = "light"
    • brightness ≤ 128 → 深色环境 → vim.o.background = "dark"

⚙️ Neovim 内部

  1. background 选项

    • Neovim 内置选项,用于告知主题当前环境类型
  2. 主题响应

    1
    2
    3
    4
    background = { 
    light = "latte", -- vim.o.background = "light" 时使用
    dark = "mocha", -- vim.o.background = "dark" 时使用
    },
  3. 自动监听:使用 OptionSet autocmd 监听 background 选项变化,实时切换主题

🔄 工作流程

1
2
3
4
5
6
7
8
9
10
11
Quickshell 切换日夜模式

更新 colors.json 文件

Neovim 启动时读取文件

计算背景色亮度

设置 vim.o.background

触发主题自动切换

以下是我的./.config/nvim/lua/plugins/catppuccin.lua主题文件的配置,可作参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
return {
"catppuccin/nvim",
name = "catppuccin",
priority = 1000,
config = function()
require("catppuccin").setup({
background = {
light = "latte", -- 浅色环境使用 latte
dark = "mocha", -- 深色环境使用 mocha
},
transparent_background = false, -- 建议false
show_end_of_buffer = false,
term_colors = false,
dim_inactive = {
enabled = false,
shade = "dark",
percentage = 0.15,
},
styles = {
comments = { "italic" },
conditionals = { "italic" },
loops = {},
functions = {},
keywords = {},
strings = {},
variables = {},
},
integrations = {
cmp = true,
gitsigns = true,
nvimtree = true,
treesitter = true,
telescope = true,
-- 根据你的插件添加更多集成
},
})

-- 主题检测(可选 - 适配你的桌面环境)
local function detect_system_theme()
-- 示例:检查系统配置文件
local theme_file = vim.fn.expand("~/.local/state/quickshell/user/generated/colors.json")
if vim.fn.filereadable(theme_file) == 1 then
local success, content = pcall(vim.fn.readfile, theme_file)
if success then
local text = table.concat(content, "\n")
local bg_color = text:match('"background":%s*"(#[%w]+)"')
if bg_color then
-- 计算颜色亮度
local hex = bg_color:gsub("#", "")
local r = tonumber(hex:sub(1, 2), 16) or 0
local g = tonumber(hex:sub(3, 4), 16) or 0
local b = tonumber(hex:sub(5, 6), 16) or 0
local brightness = (r * 299 + g * 587 + b * 114) / 1000

vim.o.background = brightness > 128 and "light" or "dark"
return true
end
end
end

return false
end

-- 根据 background 选项应用对应主题
local function apply_theme()
if vim.o.background == "dark" then
vim.cmd.colorscheme("catppuccin-mocha")
else
vim.cmd.colorscheme("catppuccin-latte")
end
end

-- 初始化
if not detect_system_theme() then
-- 如果检测失败,使用默认设置
vim.o.background = "light" -- 或 "dark",根据个人偏好
end

apply_theme()

-- 监听 background
vim.api.nvim_create_autocmd("OptionSet", {
pattern = "background",
callback = apply_theme,
})

-- 手动切换
vim.api.nvim_create_user_command('ThemeLight', function()
vim.o.background = "light"
end, { desc = '切换到浅色主题' })

vim.api.nvim_create_user_command('ThemeDark', function()
vim.o.background = "dark"
end, { desc = '切换到深色主题' })

-- 快捷键(可选)
vim.keymap.set('n', '<leader>tl', ':ThemeLight<CR>', { desc = '浅色主题' })
vim.keymap.set('n', '<leader>td', ':ThemeDark<CR>', { desc = '深色主题' })
end,
}

注意事项

⚠️ 配置文件路径依赖

Quickshell 数据路径

  • 当前路径:~/.local/state/quickshell/user/generated/colors.json
  • 如果 Quickshell 配置更改了数据生成路径,需要同步更新 Neovim 配置中的路径

🔧 配置维护

  1. 主题优先级

    • Catppuccin 设置为 priority = 1000,确保在其他主题之前加载
    • Github-theme 设为 lazy = true,避免冲突
  2. 备用机制

    • 如果颜色文件读取失败,默认设置为浅色模式
    • 保留手动切换功能作为备用选项

🐛 故障排除

  1. 主题不切换

    • 检查 colors.json 文件是否存在和可读
    • 在 Neovim 中运行 :echo vim.o.background 查看检测结果
    • 使用 :messages 查看是否有错误信息
  2. 颜色不协调

    • 检查透明背景设置:transparent_background = false
    • 确认终端颜色序列正常:cat ~/.local/state/quickshell/user/generated/terminal/sequences.txt
  3. 手动测试

    1
    2
    3
    -- 在 Neovim 中测试
    :lua print(vim.fn.expand("~/.local/state/quickshell/user/generated/colors.json"))
    :lua print(vim.fn.filereadable(vim.fn.expand("~/.local/state/quickshell/user/generated/colors.json")))

📂 相关文件位置

  • Neovim 主题配置~/.config/nvim/lua/plugins/catppuccin.lua
  • Quickshell 颜色数据~/.local/state/quickshell/user/generated/colors.json
  • 终端颜色序列~/.local/state/quickshell/user/generated/terminal/sequences.txt
  • Quickshell 主配置~/.config/illogical-impulse/config.json

我的环境:Arch Linux + Hyprland +illogical-impulse(dot-file) + Neovim + LazyVim


hyprland end4自动切换neovim主题
https://inkcodes.com/2025/09/04/hyprland end4自动切换neovim主题/
作者
Specialhua
发布于
2025年9月4日
更新于
2025年9月4日
许可协议